javascript 您所在的位置:网站首页 相机 放大 javascript

javascript

2024-07-14 01:26| 来源: 网络整理| 查看: 265

我正在为THREE.js应用程序使用正交摄影机。本质上,此摄像机将以2D形式向用户呈现场景(用户可以选择在2D和3D摄像机之间切换)。本相机可以平移和缩放到鼠标点。我有平移工作,也有缩放工作,但没有缩放到鼠标点。这是我的代码:

import React from 'react'; import T from 'three'; let panDamper = 0.15; let OrthoCamera = React.createClass({ getInitialState: function () { return { distance: 150, position: { x: 8 * 12, y: 2 * 12, z: 20 * 12 }, }; }, getThreeCameraObject: function () { return this.camera; }, applyPan: function (x, y) { // Apply pan by changing the position of the camera let newPosition = { x: this.state.position.x + x * -1 * panDamper, y: this.state.position.y + y * panDamper, z: this.state.position.z }; this.setState({position: newPosition}); }, applyDirectedZoom: function(x, y, z) { let zoomChange = 10; if(z < 0) zoomChange *= -1; let newDistance = this.state.distance + zoomChange; let mouse3D = { x: ( x / window.innerWidth ) * 2 - 1, y: -( y / window.innerHeight ) * 2 + 1 }; let newPositionVector = new T.Vector3(mouse3D.x, mouse3D.y, 0.5); newPositionVector.unproject(this.camera); newPositionVector.sub(this.camera.position); let newPosition = { x: newPositionVector.x, y: newPositionVector.y, z: this.state.position.z }; this.setState({ distance: newDistance, position: newPosition }); }, render: function () { let position = new T.Vector3(this.state.position.x, this.state.position.y, this.state.position.z); let left = (this.state.distance / -2) * this.props.aspect + this.state.position.x; let right = (this.state.distance / 2) * this.props.aspect + this.state.position.x; let top = (this.state.distance / 2) + this.state.position.y; let bottom = (this.state.distance / -2) + this.state.position.y; // Using react-three-renderer // https://github.com/toxicFork/react-three-renderer return this.camera = camera}/> } }); module.exports = OrthoCamera; 朝鼠标点进行了一些缩放,但似乎不稳定。我想保留2D View ,所以在缩放时,我还要移动相机(而不是使用非垂直目标,这会杀死2D效果)。

我从this question获得了提示。据我所知,我已经成功转换为mouse3D中的THREE.js坐标(请参阅this question的答案)。

因此,在进行此设置后,如何使用正交摄影机并保持二维 View 将鼠标点(mouse3D)平滑缩放?提前致谢。

最佳答案

假设您有一个由世界坐标中的位置和注视(或枢轴)点描述的摄像机,则放大(或远离)特定点的核心非常简单。

您的表示似乎更简单:仅是一个位置/距离对。我没有看到旋转组件,因此我假设您的摄影机是自顶向下的正交摄影机。

在这种情况下,您的观察点(不需要)只是(position.x, position.y - distance, position.z)。

在一般情况下,您要做的就是在保持相机法线(方向)的同时,将相机位置和注视点都移向变焦点。请注意,无论投影类型或相机旋转如何,此功能均有效。编辑(2020/05/01):使用正交投影时,这不是您要做的全部(请参阅底部的更新)。

如果您考虑一下,这就是在3D点缩放时发生的情况。您一直朝着相同的方向前进,但您却越来越近(没有到达目标)。

例如,如果要缩放1.1倍,可以想象将连接相机位置和缩放点的 vector 缩放1 / 1.1。

您可以通过简单地插值来做到这一点:

var newPosition = new THREE.Vector3(); newPosition.x = (orgPosition.x - zoomAt.x) / zoomFactor + zoomAt.x; newPosition.y = (orgPosition.y - zoomAt.y) / zoomFactor + zoomAt.y; newPosition.z = (orgPosition.z - zoomAt.z) / zoomFactor + zoomAt.z; 就像我上面说的,在您的情况下,您实际上不需要更新观察点,然后计算新的距离。您的新距离将是:var newDistance = newPosition.y 那应该做。

如果要设置位置/视点与位置/缩放点对之间的最小和最大距离限制,则只会稍微复杂一点(主要是在一般情况下)。

更新(2020/05/01):

我只是意识到,上述内容虽然正确(除了遗漏了一个小步骤,但非常重要的步骤除外),但这并不是对OP问题的完整答案。在正交模式下更改相机的位置当然不会更改要渲染的图形的比例。为此,必须更新相机的投影矩阵(即,必须更改正投影的左,右,顶部和底部参数)。

因此,许多图形库在其正交摄影机类中都包含一个比例因子,正是这样。我没有ThreeJS的经验,但我认为该属性称为“缩放”。

因此,总结一切:

var newPosition = new THREE.Vector3(); newPosition.x = (orgPosition.x - zoomAt.x) / zoomFactor + zoomAt.x; newPosition.y = (orgPosition.y - zoomAt.y) / zoomFactor + zoomAt.y; newPosition.z = (orgPosition.z - zoomAt.z) / zoomFactor + zoomAt.z; myCamera.zoom = myCamera.zoom * zoomFactor myCamera.updateProjectionMatrix() 如果要改用上面的正交摄影机类代码,则可能必须更改计算左,右,上和下的部分,并在计算中添加比例因子。这是一个例子:var aspect = this.viewportWidth / this.viewportHeight var dX = (this.right - this.left) var dY = (this.top - this.bottom) / aspect var left = -dX / (2 * this.scale) var right = dX / (2 * this.scale) var bottom = -dY / (2 * this.scale) var top = dY / (2 * this.scale) mat4.ortho(this.mProjection, left, right, bottom, top, this.near, this.far)

关于javascript - THREE.js正交相机放大到鼠标指向,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39905892/



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有